# -*- coding: utf-8 -*-
"""
多线程执行任务时，我们所关心的问题是如优雅的退出当前正在执行的任务。正如大家知道那样，如果强制终止任务（kill -9），
可能会使当前执行到一半的任务因为强制退出而使数据不一致，或者一些资源不能正常释放回收。
所以我们应该用 kill -int/hum/term 等信号通知程序，让程序可以在结束前做清理操作。
"""
import signal
import time
import threading

from common.utils import track_logging

_LOGGER = track_logging.getLogger(__name__)


class ServiceExit(Exception):
    pass


class GracefulExitedExecutor(object):
    def __init__(self, group_name, tasks):
        self.group_name = group_name
        self.tasks = tasks
        signal.signal(signal.SIGTERM, self.service_shutdown)
        signal.signal(signal.SIGINT, self.service_shutdown)

    def start(self):
        _LOGGER.error("the task group [%s] is starting" % self.group_name)
        try:
            for t in self.tasks:
                t.start()

            while True:
                for t in self.tasks:
                    if not t.isAlive():
                        _LOGGER.info(
                            "the task in group is died: thread: [%s] in group: [%s] ..." % (t, self.group_name))
                        raise ServiceExit()
                time.sleep(1)
        except ServiceExit:
            for t in self.tasks:
                t.shutdown_flag.set()
            for t in self.tasks:
                t.join()
        _LOGGER.error("the task group is exited, group name: [%s]" % self.group_name)

    def service_shutdown(self, signum, frame):
        raise ServiceExit


class Thread(threading.Thread):
    def __init__(self, *args, **kwargs):
        threading.Thread.__init__(self, *args, **kwargs)
        self.shutdown_flag = threading.Event()
